package com.foo.designpattern.templatemethod;

/**
 * com.foo.designpattern.templatemethod
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-05-13 14:22.
 *
 * @Description 抽象模板角色类(Abstract Template)
 * 模板方法所代表的行为成为顶级行为，其逻辑称为顶级逻辑。
 * 抽象模板角色(Abstract Template)有如下责任：
 * 1、定义了一个或多个抽象操作，以便让子类实现。这种抽象操作叫做基本操作，它们是一个顶级逻辑的组成步骤。
 * 2、定义并实现了一个模板方法。这个模板方法一般是一个具体方法，它给出了一个顶级逻辑的骨架，
 * 而逻辑的组成步骤在相应的抽象操作中，推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
 */

public abstract class AbstractTemplate {
    /**
     * Template Method:模板方法
     * 模板方法:一个模板方法是定义在抽象类中的，把基本操作方法组合在一起形成了一个总算法或一个总行为的方法。
     * 一个抽象方法可以有任意多个模板方法，而不仅限于一个。每一个模板方法都可以调用任意多个具体方法。
     * 本例中模板方法为 makeMobile(),定义一个模板方法来控制生产手机的流程。
     */
    public void makeMobile() {
        /**
         * 调用基本方法
         * 基本方法可以分为三种：抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。
         */

        // 子类不实现且不能置换的方法：确定要生产手机的屏幕尺寸。
        this.makeMobileSize();
        // 子类必须实现这些方法：确定要生产手机的运行内存、操作系统、颜色。
        this.makeDifferentRAM();
        this.makeDifferentOS();
        this.makeDifferentColor();
        // 子类可选择实现的方法：厂商的一些其他定制信息,比如要贴什么品牌。
        this.makeDifferentBrand();
        // 以上模板已经规定好了
        System.out.println("= = = = 华丽丽的分割线 = = = =");
    }

    /**
     * Concrete Method:具体方法
     * 具体方法：一个具体方法由抽象类声明并实现，而子类并不实现或置换。
     * 本例中具体方法为 makeMobileSize(),定义一个方法控制手机只能生产屏幕大小为5.5寸的手机。
     */
    private final void makeMobileSize() {
        System.out.println("生产一个屏幕大小为5.5寸的手机");
    }

    /**
     * Abstract Method:抽象方法
     * 抽象方法：一个抽象方法由抽象类声明，由具体子类实现。
     */

    // 定义抽象的方法来完成不同的生产细节：不同运行内存的手机
    protected abstract void makeDifferentRAM();

    // 定义抽象的方法来完成不同的生产细节：不同操作系统的手机
    protected abstract void makeDifferentOS();

    // 定义抽象的方法来完成不同的生产细节：不同颜色的手机
    protected abstract void makeDifferentColor();


    /**
     * Hook Method:钩子方法
     * 钩子方法：一个钩子方法由抽象类声明并实现，而子类会加以扩展。
     * 通常抽象类给出的实现是一个空实现，作为方法的默认实现。
     */
    protected void makeDifferentBrand() {
    }

}
